package cn.wsn2018.tools.ctrl;

import cn.wsn2018.tools.common.CommonValue;
import cn.wsn2018.tools.model.MySessionContext;
import cn.wsn2018.tools.model.SystemConfig;
import cn.wsn2018.tools.service.SecUserService;
import cn.wsn2018.tools.service.UserService;
import cn.wsn2018.tools.util.*;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


@RestController
@RequestMapping("/protocol")
public class UserController {
    private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;
    @Autowired
    private SecUserService secUserService;

    @CrossOrigin
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    /**
     * 处理前端登录表单，前端填写用户名密码经过验证之后返回json字符串
     */
    public void login(@RequestParam("username") String username,
                      @RequestParam("password") String password,
                      @RequestParam("timeline") String timeline,
                      @RequestParam("flag")Boolean flag,
                      HttpServletRequest request, HttpServletResponse response)throws Exception{
        ServletUtil.getInstance().requestOperating(request);
        HttpSession session = request.getSession(true);

        //记录此线程的用户名
        ThreadLocal<String> localUserName = ThreadUtil.getThreadLocalUserName();
        localUserName.set(username);

        boolean isLogined=false;//标识此账户是否已经登录在线
        if(session.getId()!=null)
            isLogined=checkIfLoginedbyOthers(username,session.getId());
        //登录函数
        String json=userService.dealUserLogin(username,password,isLogined,flag,request);

        //新鲜性验证，防止重放攻击
        logger.info("frontTime:"+timeline);
        if(StorageUtil.getInstance().containsTimeLine(timeline)){
            json=JsonUtil.failedJson(CommonValue.JSON_LOGIN_FAILED_REPLAY);
        }
        else{
            StorageUtil.getInstance().setTimeLine(timeline);
        }
        if(checkUserMaxConcurrency()){
            json=JsonUtil.failedJson(CommonValue.JSON_LOGIN_FAILED_CONCURRENCY);
        }
        JSONObject jsonObject = JSONObject.fromObject(json);
        String state = jsonObject.getJSONObject("meta").optString("state");
        if("success".equals(state)){
            //MySessionContext myc= MySessionContext.getInstance();
            String role = jsonObject.getJSONObject("data").optString("role");
            session.setAttribute("username",username);
            session.setAttribute("role",role);
            //myc.addSession(session);
            response.setHeader("token",session.getId());
            //在全局内存处获取在线用户列表并添加在线用户

            StorageUtil.getInstance().removeSessions(session.getId());
            StorageUtil.getInstance().setLoginSessions(username,session.getId());
            MySessionContext.getInstance().addSession(session);
            System.out.println(MySessionContext.getInstance().getAllId());
            Map<String,String> onlineUserMap=StorageUtil.getInstance().getLoginSessions();
            logger.info("onLineMaps:"+onlineUserMap.toString());
            //session.setMaxInactiveInterval(10);
            logger.info("sessionMaxInterval:"+session.getMaxInactiveInterval());
            ServletUtil.getInstance().responseOperating(response, json);
        }
        else {
            ServletUtil.getInstance().responseOperating(response, json);
        }

    }
    @CrossOrigin
    @RequestMapping(value = "/logout",method = RequestMethod.POST)
    /**
     * 退出登录
     */
    public void logout(@RequestParam("token") String token,HttpServletRequest request,HttpServletResponse response)throws Exception{
        MySessionContext myc= MySessionContext.getInstance();
        HttpSession session = myc.getSession(token);
        String myUsername = session.getAttribute("username").toString();
        //myc.delSession(session);
        session.invalidate();

        //记录线程和用户名的ThreadLocal
        ThreadLocal<String> localUserName = ThreadUtil.getThreadLocalUserName();
        //防止内存泄露
        localUserName.remove();

        //用户下线，则将请求的时间戳给移除
        ConcurrentHashMap<String, String> userTimeStampMap = ServletUtil.getUserTimeStampMap();
        userTimeStampMap.remove(token);

        if(request.getSession(false)==null){
            LogUtil.produceLogs(myUsername,CommonValue.LOGOUT_TYPE,CommonValue.LOGOUT_LOGINFO,CommonValue.LOG_TYPE_BUS,CommonValue.SUCCESS);
            String json = JsonUtil.successJson(CommonValue.JSON_LOGOUT_SUCCESS,null,null);
            //将在线列表中的该用户移除
            StorageUtil.getInstance().removeUser(myUsername);
            Map<String,String> onlineUserMap=StorageUtil.getInstance().getLoginSessions();
            logger.info("onLineMaps Remain: "+onlineUserMap.toString());
            ServletUtil.getInstance().responseOperating(response, json);
        }else {
            LogUtil.produceLogs(myUsername,CommonValue.LOGOUT_TYPE,CommonValue.LOGOUT_LOGINFO,CommonValue.LOG_TYPE_BUS,CommonValue.FAILED);
            String json = JsonUtil.successJson(CommonValue.JSON_LOGOUT_FAILED,null,null);
            ServletUtil.getInstance().responseOperating(response, json);
        }
    }
    @CrossOrigin
    @RequestMapping(value = "/checkLogin",method = RequestMethod.GET)
    /**
     * 确认登录
     */
    public void checkLogin(HttpServletRequest request,HttpServletResponse response)throws Exception{
        String json = JsonUtil.successJson(CommonValue.JSON_LOGIN_ONLINE,null,null);
        ServletUtil.getInstance().responseOperating(response, json);
    }


    @CrossOrigin
    @RequestMapping(value = "/users",method = RequestMethod.POST)
    /**
     * 处理前端添加用户表单，前端填写用户名经过验证之后返回json字符串
     */
    public void createUser(@RequestParam("username") String username,
                           @RequestParam("role") String role,
                           @RequestParam("token") String token, HttpServletRequest request, HttpServletResponse response)throws Exception{
        ServletUtil.getInstance().requestOperating(request);
        MySessionContext myc= MySessionContext.getInstance();
        HttpSession session = myc.getSession(token);
        String myUsername = session.getAttribute("username").toString();
        String myRole = session.getAttribute("role").toString();
        if(CommonValue.ROLE_ADMIN.equals(myRole)){
            String json = userService.dealUserCreate(username,role,myUsername);
            ServletUtil.getInstance().responseOperating(response, json);
        }else {
            LogUtil.produceLogs(myUsername,CommonValue.CREATE_TYPE,CommonValue.CREATE_USER_LOGINFO+username,CommonValue.LOG_TYPE_BUS,CommonValue.FAILED);
            String json = JsonUtil.failedJson(CommonValue.JSON_ROLE_ERROR);
            ServletUtil.getInstance().responseOperating(response, json);
        }
    }

    @CrossOrigin
    @RequestMapping(value = "/admin",method = RequestMethod.POST)
    /**
     * 添加管理员
     */
    public void createAdmin(@RequestParam("username") String username,
                           @RequestParam("token") String token, HttpServletRequest request, HttpServletResponse response)throws Exception{
        ServletUtil.getInstance().requestOperating(request);
        if(username!=null&&token!=null&&token.equals("wsnwsn")){
            String json = userService.dealAdminCreate(username);
            ServletUtil.getInstance().responseOperating(response, json);
        }else {
            String json = JsonUtil.failedJson(CommonValue.JSON_ROLE_ERROR);
            ServletUtil.getInstance().responseOperating(response, json);
        }


    }


    @CrossOrigin
    @RequestMapping(value = "/checkFirst",method = RequestMethod.GET)
    /**
     * 是否第一次登录
     * 后面顺便也加入了用户的授权状态--By sds
     */
    public void checkFirstLogin(@RequestParam("username") String username,HttpServletRequest request, HttpServletResponse response) throws Exception {
        ServletUtil.getInstance().requestOperating(request);
        String json = userService.dealFirstCheck(username);
        ServletUtil.getInstance().responseOperating(response, json);

    }
    @CrossOrigin
    @RequestMapping(value = "/users/username",method = RequestMethod.POST)
    /**
     * 修改用户密码
     */
    public void updateUser(@RequestParam("username") String username,
                           @RequestParam("formerPassword") String formerPassword,
                           @RequestParam("newPassword") String newPassword,
                           @RequestParam("token") String token, HttpServletRequest request, HttpServletResponse response)throws Exception{
        ServletUtil.getInstance().requestOperating(request);
        MySessionContext myc= MySessionContext.getInstance();
        HttpSession session = myc.getSession(token);
        String myUsername = session.getAttribute("username").toString();
        String json = userService.dealUserUpdate(username,formerPassword,newPassword,myUsername);
        ServletUtil.getInstance().responseOperating(response, json);
    }
    @CrossOrigin
    @RequestMapping(value = "/users/username",method = RequestMethod.GET)
    /**
     * 查询用户详情
     */
    public void findUsers(@RequestParam("username") String username,
                          HttpServletRequest request, HttpServletResponse response)throws Exception{
        ServletUtil.getInstance().requestOperating(request);
        String json = userService.dealOneUserFind(username);
        ServletUtil.getInstance().responseOperating(response, json);
    }
    @CrossOrigin
    @RequestMapping(value = "/userInfo",method = RequestMethod.GET)
    /**
     * 查询当前会话用户详情
     */
    public void findUserInfo(HttpServletRequest request, HttpServletResponse response)throws Exception{
        ServletUtil.getInstance().requestOperating(request);
        HttpSession session = request.getSession(true);
        String username = StorageUtil.getInstance().getNameById(session.getId());
        String json = userService.dealOneUserFind(username);
        ServletUtil.getInstance().responseOperating(response,json);
    }

    @CrossOrigin
    @RequestMapping(value = "/users/role",method = RequestMethod.GET)
    /**
     * 按角色查询用户
     */
    public void findUsers(@RequestParam("role") String role,
                          @RequestParam("pageNum") String pageNum,
                          @RequestParam("pageSize")String pageSize,
                          HttpServletRequest request, HttpServletResponse response)throws Exception{
        ServletUtil.getInstance().requestOperating(request);
        String json = userService.dealUsersFindByRole(role,pageNum,pageSize);
        ServletUtil.getInstance().responseOperating(response, json);
    }
    @CrossOrigin
    @RequestMapping(value = "/users",method = RequestMethod.GET)
    /**
     * 查询所有用户
     */
    public void findUsers(@RequestParam("pageNum") String pageNum,
                          @RequestParam("pageSize")String pageSize,
                          HttpServletRequest request, HttpServletResponse response)throws Exception{
        ServletUtil.getInstance().requestOperating(request);
        String json = userService.dealAllUsersFind(pageNum,pageSize);
        ServletUtil.getInstance().responseOperating(response, json);
    }
    @CrossOrigin
    @RequestMapping(value = "/delusername",method = RequestMethod.POST)
    /**
     * 删除用户
     */
    public void deleteUser(@RequestParam("username") String username,
                           @RequestParam("token") String token,HttpServletRequest request,HttpServletResponse response)throws Exception{
        ServletUtil.getInstance().requestOperating(request);
        MySessionContext myc= MySessionContext.getInstance();
        HttpSession session = myc.getSession(token);
        String myUsername = session.getAttribute("username").toString();
        String myRole = session.getAttribute("role").toString();
        if(CommonValue.ROLE_ADMIN.equals(myRole)){
            String json = userService.dealUserDelete(username,myUsername);
            ServletUtil.getInstance().responseOperating(response, json);
        }else {
            LogUtil.produceLogs(myUsername,CommonValue.DELETE_TYPE,CommonValue.DELETE_USER_LOGINFO+username,CommonValue.LOG_TYPE_BUS,CommonValue.FAILED);
            String json = JsonUtil.failedJson(CommonValue.JSON_ROLE_ERROR);
            ServletUtil.getInstance().responseOperating(response, json);
        }
    }

    /**
     * 用于判断该用户是否已经登陆过
     * @param username
     * @return
     */
    private boolean checkIfLoginedbyOthers(String username,String token){
        Map<String,String> onlineUserMap=StorageUtil.getInstance().getLoginSessions();
        if(onlineUserMap.containsKey(username)) {
            String sessionID=onlineUserMap.get(username);
            if(!sessionID.equals(token)) {
                //让前一个人的session失效
                MySessionContext myc = MySessionContext.getInstance();
                HttpSession session = myc.getSession(sessionID);
                if(session!=null)
                    session.invalidate();
                onlineUserMap.remove(username);
                //把自己的sessionID信息加进去
                onlineUserMap.put(username, token);
                return true;
            }
            else{
                return  false;
            }
        }
        return false;
    }

    /**
     * 用于登录前判断是否达到用户最大并发数
     * @return
     */
    private boolean checkUserMaxConcurrency(){
        //获取在线用户列表
        Map<String,String> onlineUserMap=StorageUtil.getInstance().getLoginSessions();
        //获取系统配置
        SystemConfig config=secUserService.getStorageSystemConfig();
        //获取系统配置的最大并发数
        Integer maxNum=Integer.parseInt(config.getConcurrentMaxNum());
        if (onlineUserMap.size()>=maxNum){
            return true;
        }
        else{
            return false;
        }

    }



}
